from loa_game import BLACK, WHITE, EMPTY
from loa_game import MoveAction, SpinAction
# -*- coding:utf-8 -*-
"""
Created on May 31, 2011

@author: bob
"""
COM_ROW = 0
COM_COL = 1

MIN_ROW = 0
MIN_COL = 1
MAX_ROW = 2
MAX_COL = 3
INFINITY = 1.0e400

class Com():
    
    def __init__(self, gameState):
        self.gameState = gameState
        self.board = gameState.board
        self.sumMinDistances = {2:2, 3:2, 4:4, 5:4, 6:6, 7:7,8:8,9:8,10:10,11:12,12:14}
        self.blackCom = None
        self.whiteCom = None
        
        initAreaCoor = len(self.board) / 2
        self.areaParams = {}
        self.countCenterOfMass()
#        print self.areaParams
    
    def countCenterOfMass(self):
        blackRow, whiteRow, blackCol, whiteCol = 0,0,0,0
        board = self.board
        bLength = len(board)
        nb, nw = float(self.gameState.blacks), float(self.gameState.whites)
        wMinRow,wMinCol,wMaxRow,wMaxCol = bLength-1,bLength-1,0,0
        bMinRow,bMinCol,bMaxRow,bMaxCol = bLength-1,bLength-1,0,0
        for i in range(0, bLength):
            for j in range(0, bLength):
                if board[i][j] == BLACK:
                    blackRow = blackRow + i
                    blackCol = blackCol + j
                    if i<bMinRow:
                        bMinRow = i
                    if i>bMaxRow:
                        bMaxRow = i
                    if j<bMinCol:
                        bMinCol = j
                    if j>bMaxCol:
                        bMaxCol = j
                elif board[i][j] == WHITE:
                    whiteRow = whiteRow + i
                    whiteCol = whiteCol + j
                    if i<wMinRow:
                        wMinRow = i
                    if i>wMaxRow:
                        wMaxRow = i
                    if j<wMinCol:
                        wMinCol = j
                    if j>wMaxCol:
                        wMaxCol = j
        self.areaParams = {WHITE:{MIN_ROW:wMinRow,MAX_ROW:wMaxRow,MIN_COL:wMinCol,MAX_COL:wMaxCol},
                           BLACK:{MIN_ROW:bMinRow,MAX_ROW:bMaxRow,MIN_COL:bMinCol,MAX_COL:bMaxCol}}
        self.blackCom, self.whiteCom = ((blackRow/nb,blackCol/nb),(whiteRow/nw,whiteCol/nw))
    
    def getCom(self):
        return {WHITE:self.whiteCom, BLACK:self.blackCom}
    
    def updateCom(self,color, oldLoc, newLoc): 
        if color == WHITE:
            oldCom = self.whiteCom
            n = self.gameState.whites
        else:
            oldCom = self.blackCom
            n = self.gameState.blacks
        sumLocs = (n*oldCom[COM_ROW]-oldLoc[COM_ROW], n*oldCom[COM_COL]-oldLoc[COM_COL])
        if newLoc is None:
            n = n - 1
        else:
            sumLocs = sumLocs[COM_ROW]+newLoc[COM_ROW],sumLocs[COM_COL]+newLoc[COM_COL] 
        newCom = (sumLocs[COM_ROW]/n, sumLocs[COM_COL]/n)
        if color == WHITE:
            self.whiteCom = newCom
        else:
            self.blackCom = newCom
    
    def updateComMove(self,color, oldLoc,newLoc,gameState):
        self.updateCom(color, oldLoc, newLoc)
        self.board = gameState.board
        self.gameState = gameState
        
    def updateComSpin(self,row,col,game):
        self.updateCom(self.board[row][col], (row,col), (row,col+1))
        self.updateCom(self.board[row][col+1], (row,col+1), (row+1,col+1))
        self.updateCom(self.board[row+1][col+1], (row+1,col+1), (row+1,col))
        self.updateCom(self.board[row+1][col], (row+1,col), (row,col))
        self.gameState = game
        self.board = game.board
    
    def updateComAction(self,action,gameState):
        if isinstance(action, MoveAction):
            initRow, initCol = action.row,action.col
            endRow, endCol = initRow+action.direction.delta[0],initCol+action.direction.delta[1] 
            self.updateComMove(self.board[initRow][initCol], (initRow, initCol),
                                (endRow, endCol), gameState)
        else:
            self.updateComSpin(action.row, action.col, gameState)
               
 
    def concentration(self, color):
        pieceCount, distSum = 0, 0
        if color == WHITE:
            pieceLim = self.gameState.whites
            com = self.whiteCom
        else:
            pieceLim = self.gameState.blacks
            com = self.blackCom
        for i in range(0,self.gameState.size):
            for j in range(0,self.gameState.size):
                if self.board[i][j] == color:
                    pieceCount = pieceCount + 1
                    distRow = abs(i-com[COM_ROW])
                    distCol = abs(j-com[COM_COL])
                    distSum = distSum + max(distRow, distCol)
                    if pieceCount == pieceLim:
                        diff = float(distSum - self.sumMinDistances[pieceCount])
                        if diff == 0:
                            return INFINITY
                        return 1 / diff
                
                
                
    def getEnclosingArea(self,color):
        dict = self.areaParams[color]
        rowDiff = float(dict[MAX_ROW]-dict[MIN_ROW]+1)
        colDiff = float(dict[MAX_COL]-dict[MIN_COL]+1)
#        print colDiff*rowDiff
        return len(self.board)/(colDiff*rowDiff)       
                
                
                
                
                
                